<?php

namespace Fize\Think\template;

use Exception;
use think\template\TagLib as Common;
use think\Template;
use think\facade\App;
use think\facade\Config;

/**
 * 标签自定义
 *
 * 支持组件变量定义
 * @todo 待修复
 */
class TagLib extends Common
{

    /**
     * @var array 内部视图配置
     */
    protected $config;

    /**
     * @var Template 内部视图
     */
    protected $view;

    /**
     * @var array TAG内变量
     */
    protected $assigns = [];

    /**
     * 架构函数
     * @param Template $template 模板引擎对象
     */
    public function __construct(Template $template)
    {
        parent::__construct($template);
        $this->config = Config::get('view');
        $path = App::getAppPath() . 'view' . DIRECTORY_SEPARATOR;
        $this->config['view_path'] = $path;
        $this->view = new Template($this->config);
    }

    /**
     * 模板变量赋值
     * @param string $name  变量名
     * @param mixed  $value 变量值
     */
    protected function assign(string $name, $value)
    {
        $this->assigns[$name] = $value;
    }

    /**
     * 解析和获取模板内容 用于输出
     * @access public
     * @param string $template 模板文件名或者内容
     * @return string
     */
    protected function fetch(string $template): string
    {
        $template = $this->parseTemplateFile($template);
        $content = file_get_contents($template);
        $this->view->parse($content);
        if ($this->assigns) {
            // 备份原视图变量
            $key = 'TAG_VAL_' . md5($template);
            $this->tpl->assign([$key => $this->assigns]);
            $ctbgn = '';
            $ctbgn .= '<?php $__VIEW_DEFINED_VARS__ = get_defined_vars();  ?>';
            $ctbgn .= '<?php extract($' . $key . ');  ?>';

            // 还原原视图变量
            $ctend = '';
            foreach (array_keys($this->assigns) as $valkey) {
                $ctend .= '<?php unset($' . $valkey . '); ?>';
            }
            $ctend .= '<?php unset($__VIEW_DEFINED_VARS__["' . $key . '"]); ?>';
            $ctend .= '<?php extract($__VIEW_DEFINED_VARS__);  ?>';

            $content = $ctbgn . "\r\n" . $content . "\r\n" . $ctend;
        }
        return $content;
    }

    /**
     * 解析模板文件名
     * @access private
     * @param string $template 文件名
     * @return string
     */
    private function parseTemplateFile(string $template): string
    {
        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {

            if (0 !== strpos($template, '/')) {
                $template = str_replace(['/', ':'], $this->config['view_depr'], $template);
            } else {
                $template = str_replace(['/', ':'], $this->config['view_depr'], substr($template, 1));
            }

            $template = $this->config['view_path'] . $template . '.' . ltrim($this->config['view_suffix'], '.');
        }
        if (is_file($template)) {
            return $template;
        }
        throw new Exception('template not exists:' . $template);
    }

    /**
     * 从属性中获取参数值
     * @param array  $attr    属性
     * @param string $key     名称，如果以$开头，则获取其值
     * @param mixed  $default 默认值
     * @return mixed
     */
    protected function getattr(array $attr, string $key, $default = null)
    {
        if (!isset($attr[$key])) {
            return $default;
        }
        $value = $attr[$key];
        if (substr($value, 0, 1) == '$') {
            $key = substr($value, 1);
            $value = $this->tpl->get($key);
            if (is_null($value)) {
                $value = $default;
            }
        }
        return $value;
    }
}